namespace FluentMvc.MvcIntegration
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq.Expressions;

    public class TemplateConfiguration<TModel, TProperty> where TModel : class
    {
        private readonly ModelContext<TModel> modelContext;
        private readonly string propertyName;

        public TemplateConfiguration(Expression<Func<TModel, TProperty>> selector, ModelContext<TModel> modelContext)
        {
            propertyName = new ExpressionHandler().GetFullPropertyName(selector);
            this.modelContext = modelContext;
        }


        public TemplateConfiguration<TModel,TProperty> HiddenInput(bool disableValue = true)
        {
            var settings = modelContext.GetSettings(propertyName);
            settings.HiddenInput = true;
            settings.HiddenInputDispayValue = disableValue;
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> Display(string display)
        {
            modelContext.GetSettings(propertyName).Display = display;
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> DataType(DataType dataType)
        {
            modelContext.GetSettings(propertyName).DataType = dataType;
            return this;
        } 

        public TemplateConfiguration<TModel,TProperty> UIHint(UIHint uiHint)
        {
            modelContext.GetSettings(propertyName).UIHint = uiHint.ToString();
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> UIHint(string uiHint)
        {
            modelContext.GetSettings(propertyName).UIHint = uiHint;
            return this;
        } 

        public TemplateConfiguration<TModel,TProperty> AdditionalMetadata(string name, object value)
        {
            modelContext.GetSettings(propertyName).AdditionalMetadata.Add(name, value);
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> AdditionalMetadata(Func<Dictionary<string,object>> getMetadata)
        {
            if (getMetadata == null)
                return this;
            var setting = modelContext.GetSettings(propertyName);
            foreach (var pair in getMetadata())
                setting.AdditionalMetadata.Add(pair.Key, pair.Value);
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> DisplayFormat(string format)
        {
            modelContext.GetSettings(propertyName).DisplayFormat = format;
            return this;
        }

        public TemplateConfiguration<TModel, TProperty> EditorFormat(string format)
        {
            modelContext.GetSettings(propertyName).EditorFormat = format;
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> NullText(string text)
        {
            modelContext.GetSettings(propertyName).NullText = text;
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> ShowForEdit(bool value)
        {
            modelContext.GetSettings(propertyName).ShowForEdit = value;
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> ShowForDisplay(bool value)
        {
            modelContext.GetSettings(propertyName).ShowForDisplay = value;
            return this;
        }
 
        public TemplateConfiguration<TModel,TProperty> Order(int order)
        {
            modelContext.GetSettings(propertyName).Order = order;
            return this;
        }

        public TemplateConfiguration<TModel,TProperty> Watermark(string text)
        {
            modelContext.GetSettings(propertyName).Watermark = text;
            return this;
        } 
    }
}